﻿using ECMS.AppService.Interfaces;
using ECMS.AppService.Model.Responses;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace ECMS.Api.Token
{
    public class TokenProvider
    {

        private readonly TokenProviderOptions _options;
        private readonly IAppUserService _service;
        public TokenProvider(TokenProviderOptions options, IAppUserService service)
        {
            _options = options;
            this._service = service;
        }
        /// <summary>
        /// 生成令牌
        /// </summary>
        /// <param name="context">http上下文</param>
        /// <param name="loginname">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="role">角色</param>
        /// <returns></returns>
        public async Task<TokenResponse> GenerateToken(HttpContext context, string loginname, string password, string role)
        {
            var identity = await GetIdentity(loginname,password);
            if (identity == null)
            {
                return null;
            }
            var now = DateTime.UtcNow;
            //声明
            var claims = new Claim[]
            {
             new Claim(JwtRegisteredClaimNames.Sub,loginname),
             new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
             new Claim(JwtRegisteredClaimNames.Iat,ToUnixEpochDate(now).ToString(),ClaimValueTypes.Integer64),
             new Claim(ClaimTypes.Role,role),
             new Claim(ClaimTypes.Name,loginname)
            };
            //Jwt安全令牌
            var jwt = new JwtSecurityToken(
                issuer: _options.Issuer,
                audience: _options.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(_options.Expiration),
                signingCredentials: _options.SigningCredentials);
            //生成令牌字符串
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
            var response = new TokenResponse
            {
                Status = true,
                access_token = encodedJwt,
                expires_in = (int)_options.Expiration.TotalSeconds,
                token_type = "Bearer"
            };


            return response;
        }

        private static long ToUnixEpochDate(DateTime date)
        {
            return (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
        }
        /// <summary>
        /// 查看令牌是否存在
        /// </summary>
        /// <param name="loginname">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        private Task<ClaimsIdentity> GetIdentity(string loginname,string password)
        {
            var isValidated = _service.CheckUser(loginname, password);
            if (isValidated.Result)
            {
                return Task.FromResult(new ClaimsIdentity(new System.Security.Principal.GenericIdentity(loginname, "Token"),
                new Claim[] {
                 //new Claim(ClaimTypes.Name, loginname)
                }));
            }
            return Task.FromResult<ClaimsIdentity>(null);
        }

    }
}